package org.example.backend.service;

import org.example.backend.entity.NewsItem;
import org.springframework.stereotype.Service;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.openqa.selenium.support.ui.ExpectedConditions;

import java.net.URLEncoder;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;

@Service
public class NewsService {
    // 内部类用于相关性打分
    private static class ScoredNews {
        NewsItem news;
        int score;
        ScoredNews(NewsItem news, int score) {
            this.news = news;
            this.score = score;
        }
    }

    public List<NewsItem> searchNews(String keyword, String startDate, String endDate) {
        List<NewsItem> result = new ArrayList<>();
        // 设置 edgedriver 路径
        System.setProperty("webdriver.edge.driver", "/Users/zhangziheng/Downloads/edgedriver_mac64_m1/msedgedriver");
        EdgeOptions options = new EdgeOptions();
        options.addArguments("--headless=new");
        options.addArguments("--disable-gpu");
        WebDriver driver = new EdgeDriver(options);
        try {
            String encodedKeyword = URLEncoder.encode(keyword, "UTF-8");
            String queryUrl = "http://search.people.cn/s?keyword=" + encodedKeyword + "&st=0";
            driver.get(queryUrl);
            Thread.sleep(2000);

            WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
            wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("li.clear")));
            List<WebElement> newsList = driver.findElements(By.cssSelector("li.clear"));
            for (WebElement item : newsList) {
                WebElement aTag = item.findElement(By.cssSelector("a"));
                String title = aTag.getText();
                String url = aTag.getDomAttribute("href");
                String publisher = "";
                try {
                    WebElement contentDiv = item.findElement(By.cssSelector(".content > div:last-child"));
                    String sourceText = contentDiv.getText();
                    int idx = sourceText.indexOf("来源：");
                    if (idx >= 0) {
                        String rest = sourceText.substring(idx + 3).trim();
                        publisher = rest;
                    }
                } catch (Exception ex) {
                    // 忽略解析异常
                }
                result.add(new NewsItem(title, url, publisher, ""));
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            driver.quit();
        }

        return result;
    }

    public List<NewsItem> searchRelatedNews(String policyTitle, int size) {
        System.out.println("searchRelatedNews 方法被调用: " + policyTitle);
        List<String> validWords = new ArrayList<>();
        // 扩充无实际指向性的虚词黑名单
        List<String> stopWords = List.of(
            "的", "和", "与", "及", "为", "在", "对", "等", "关于", "通知", "意见", "办法", "规定", "政策", "公告", "通告", "方案", "决定", "管理", "印发", "征求", "答复", "批复", "补充", "修订", "调整", "补发",
            "若干措施", "措施", "促进", "进一步", "推进", "开展", "加强", "完善", "支持", "实施", "意见", "指导", "相关", "工作", "事项", "要求", "落实", "意见", "建议", "说明", "说明书", "通知书", "通报", "批转", "批示", "批文", "函", "摘要", "摘要说明", "摘要通知", "摘要通报"
        );
        // 专业词优先：可根据实际业务扩展
        List<String> domainWords = List.of("原油", "期货", "市场", "开放", "投资者", "交易所", "证券", "金融", "商品", "能源", "衍生品");
        List<String> hitDomainWords = new ArrayList<>();
        try {
            org.springframework.web.client.RestTemplate restTemplate = new org.springframework.web.client.RestTemplate();
            @SuppressWarnings("unchecked")
            java.util.Map<String, Object> segResult = (java.util.Map<String, Object>) restTemplate.postForObject(
                "http://localhost:8080/api/ai/policy/segment",
                java.util.Map.of("text", policyTitle),
                java.util.Map.class
            );
            if (segResult != null && Boolean.TRUE.equals(segResult.get("success"))) {
                @SuppressWarnings("unchecked")
                List<java.util.Map<String, Object>> keywords = (List<java.util.Map<String, Object>>) segResult.get("keywords");
                System.out.println("分词原始结果: " + keywords);
                for (java.util.Map<String, Object> kw : keywords) {
                    String word = (String) kw.get("word");
                    if (word.length() >= 2 && !stopWords.contains(word)) {
                        validWords.add(word);
                        if (domainWords.contains(word)) {
                            hitDomainWords.add(word);
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("分词有效关键词: " + validWords);
        System.out.println("命中的专业词: " + hitDomainWords);
        String searchQuery = String.join(" ", validWords);
        List<NewsItem> result = new ArrayList<>();
        List<NewsItem> all = searchNews(searchQuery.isEmpty() ? policyTitle : searchQuery, "", "");
        // 相关性打分：标题完全包含、关键词命中数、优先高相关度
        List<ScoredNews> scoredList = new ArrayList<>();
        String lowerPolicyTitle = policyTitle.toLowerCase();
        for (NewsItem news : all) {
            String lowerTitle = news.getTitle().toLowerCase();
            int hit = 0;
            int domainHit = 0;
            for (String w : validWords) {
                String lw = w.toLowerCase();
                if (!lw.isEmpty() && lowerTitle.contains(lw)) {
                    hit++;
                }
            }
            for (String dw : hitDomainWords) {
                if (!dw.isEmpty() && lowerTitle.contains(dw.toLowerCase())) {
                    domainHit++;
                }
            }
            boolean fullMatch = lowerTitle.contains(lowerPolicyTitle);
            int score = hit * 10;
            if (fullMatch) score += 100;
            if (domainHit > 0) score += 50 * domainHit; // 专业词命中加权
            // 可改为只要求命中分词关键词，专业词加分
            if (hit > 0) {
                scoredList.add(new ScoredNews(news, score));
            }
        }
        // 按分数降序排序
        scoredList.sort((a, b) -> Integer.compare(b.score, a.score));
        // 只取分数大于0的，且同名新闻只保留后面出现的
        List<NewsItem> filtered = new ArrayList<>();
        java.util.Set<String> seenTitles = new java.util.HashSet<>();
        for (int i = scoredList.size() - 1; i >= 0; i--) { // 倒序遍历，保留后面的
            ScoredNews sn = scoredList.get(i);
            String title = sn.news.getTitle();
            if (sn.score > 0 && !seenTitles.contains(title)) {
                filtered.add(0, sn.news); // 插到前面，恢复原顺序
                seenTitles.add(title);
            }
        }
        // 返回搜索链接+前size条高相关新闻
        for (int i = 0; i < Math.min(size, filtered.size()); i++) {
            result.add(filtered.get(i));
        }

        return result;
    // 内部类用于相关性打分（仅保留类级别定义）
    }
}
